package pokestar;

import objectos.Objecto;
import objectos.Pokemon;
import objectos.TipoObjecto;
import objectos.Treinador;

/**
 * @author igo
 * Classe Ataque
 * Classe que gere o ataque das personagens (uma thread por cada personagem) e causa dano às outras personagens (que não sejam do mesmo jogador)
 */
public class Ataque extends Thread {

    private Objecto o;
    private String Dono = "";
    private int dano = 0;
    private Mapa m;
    private int espera=0;
    private int x;
    private int y;
    private boolean vivo= true;

    /**
     * Constructor da thread ataque
     * @param e - Recebe um número inteiro que será o tempo de intervalo entre dois ataques.
     * @param m - Mapa ao qual o ataque terá efeito.
     * @param o - Personagem (Pokemon ou Treinador) à qual a thread se destina.
     */
    public Ataque(int e, Mapa m, Objecto o) {
        this.o = o;
        this.m = m;
        this.espera = e;

        if (o.getTipo() == TipoObjecto.TREINADOR) {
            Dono = ((Treinador) o).getInfo();
            dano = ((Treinador) o).getAtaque();
        } else if (o.getTipo() == TipoObjecto.POKEMON) {
            Dono = ((Pokemon) o).getDono();
            dano = ((Pokemon) o).getAtaque();
        }
    }

    /**
     * Método que altera a posição actual da personagem.
     */
    public void getPos() {
        for (int l = 0; l < m.getMatriz().length; l++) {
            for (int c = 0; c < m.getMatriz()[l].length; c++) {
                if (m.getMatriz()[l][c] == o) {
                    x = l;
                    y = c;
                }
            }
        }
    }

    /**
     * Método que Causa dano a todas as personagens (que não sejam do mesmo jogador que a personagem que ataca) dentro do seu range.
     */
    public void setAlvos() {
        int r = 0;
        double area_max = 0;
        if (o.getTipo() == TipoObjecto.TREINADOR) {
            r = ((Treinador) o).getRange();
        } else {
            r = ((Pokemon) o).getRange();
        }

        area_max = Math.PI * Math.pow(r, 2);
        for (int l = (x - r); l <= (x + r); l++) {
            for (int c = (y - r); c <= (y + r); c++) {
                if (l >= 0 && l < m.getMatriz().length) {
                    if (c >= 0 && c < m.getMatriz()[l].length) {
                        if (!(x == l && y == c)) {
                            Objecto tmp = m.getMatriz()[l][c];
                            double area = Math.PI * Math.pow(Math.abs(x - l) + Math.abs(y - c), 2);
                            if (area <= area_max) {
                                if (tmp.getTipo() == TipoObjecto.POKEMON) {
                                    if (!((Pokemon) tmp).getDono().equals(Dono)) {
                                        if(((Pokemon)tmp).getVida()>0)
                                            ((Pokemon) tmp).Sofre(dano);
                                    }
                                } else if (tmp.getTipo() == TipoObjecto.TREINADOR) {
                                    if (!((Treinador) tmp).getInfo().equals(Dono)) {
                                        if(((Treinador)tmp).getVida()>0)
                                            ((Treinador) tmp).Sofre(dano);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Método que faz a personagem atacar de tempo a tempo enquanto a personagem tiver viva.
     */
    public void run() {
        try {
            while(!interrupted() && vivo){
                getPos();
                setAlvos();
                sleep(espera*2);
                vivo();
            }
        } catch (InterruptedException ex) {
            //Logger.getLogger(Ataque.class.getName()).log(Level.SEVERE, null, ex);
            
        }
    }

    /**
     * Método que verifica se a personagem ainda está viva ou não.
     */
    private void vivo() {
        if (o.getTipo() == TipoObjecto.TREINADOR) {
            vivo = ((Treinador)o).estaVivo();
        } else if (o.getTipo() == TipoObjecto.POKEMON) {
            vivo = ((Pokemon)o).estaVivo();
        }
    }
}